package com.wlz.auth.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.token.TokenStore;

import javax.sql.DataSource;

/**
 *  配置授权服务器
 *     基于 数据库
 *
 *    整合redis
 *
 *
 * @author wlz
 * @desc
 * @date 2021-10-05 14:39
 */
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManagerBean;

    @Autowired
    private UserDetailsService userDetailsService;

    @Qualifier("dataSource")
    @Autowired
    private DataSource dataSource;

    @Autowired
    private TokenStore tokenStore;


    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManagerBean) // 使用密码模式需要配置
                .tokenStore(tokenStore) // 指定token存储到redis
                .reuseRefreshTokens(false) // refresh_token是否重复使用
                .userDetailsService(userDetailsService) // 刷新令牌授权包含对用户信息的检查
        .allowedTokenEndpointRequestMethods(HttpMethod.GET,HttpMethod.POST); // 支持 GET POST 请求
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.allowFormAuthenticationForClients() // 允许表单登陆认证
                // 获取密钥需要身份认证，使用单点登录时必须配置
                .tokenKeyAccess("isAuthenticated()");
        security.checkTokenAccess("permitAll()");
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

        // 获取 token
        // http://localhost:8888/oauth/token?username=wlz&password=123456&grant_type=password&client_id=client&client_secret=123456&scope=all

//        // 内存模式
//        clients.inMemory()
//                .withClient("client") // 配置 client_id
//                .secret(passwordEncoder.encode("123456")) // 配置 client_secret
//                .accessTokenValiditySeconds(3600) // 配置访问token的有效期
//                .refreshTokenValiditySeconds(864000) // 配置刷新token的有效期
//                .redirectUris("https://www.baidu.com") // 配置redirect_uri，用于授权成功后跳转
//                .scopes("all")  // 配置申请的权限范围
//                // 配置grant_type，表示授权类型 authorization_code: 授权码模式; implicit: 简化模式; password: 密码模式; client_credentials：客户端模式；refresh_token:刷新令牌;
//                .authorizedGrantTypes("authorization_code", "implicit","password","client_credentials","refresh_token");

        //password模式
        clients.withClientDetails(clientDetails());
    }

    @Bean
    public ClientDetailsService clientDetails() {
        //读取oauth_client_details表
        return new JdbcClientDetailsService(dataSource);
    }

}
